package com.liveinstars.account.application.endpoint;


import com.liveinstars.account.application.assembler.AccountAssembler;
import com.liveinstars.account.business.domain.bo.SocialWechat;
import com.liveinstars.account.business.domain.bo.User;
import com.liveinstars.account.business.service.AccountService;
import com.liveinstars.account.business.service.UserService;
import com.liveinstars.api.dto.*;
import com.liveinstars.api.facade.ImUserCentreApi;
import com.onepiece.shipelves.common.Result;
import com.onepiece.shipelves.common.enums.SystemExceptionEnum;
import com.onepiece.shipelves.common.exception.QuHuiRuntimeException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestHeader;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;
import java.util.stream.Collectors;

@RestController
public class UserInfoEndpoint implements ImUserCentreApi {
    private final static Logger logger = LoggerFactory.getLogger(UserInfoEndpoint.class);
    @Autowired
    @Qualifier("AccountService")
    private AccountService accountService;


    @Autowired
    @Qualifier("UserService")
    private UserService userService;

    @Override
    public ImGetUserInfo imGetUserInfo(@RequestParam Long uid) {
        User user = getUser(Math.toIntExact(uid));
        if(user == null) {
            return null;
        }
        return AccountAssembler.toImUserInfo(user);
    }

    @Override
    public Result<List<ImGetUserInfo>> batchImGetUserInfo(@RequestBody BatchImGetUserReq batchImGetUserReq) {
        Result<List<ImGetUserInfo>> result = new Result<>();

        List<Long> uids = batchImGetUserReq.getUids();
        List<Integer> ids = uids.stream().map(id -> id.intValue()).collect(Collectors.toList());
        List<User> users = getUsers(ids);
        List<ImGetUserInfo> collect = users.stream().map(AccountAssembler::toImUserInfo).collect(Collectors.toList());
        result.setData(collect);
        return result;
    }

    @Override
    public Result<GetUserInfo> getUserInfo(@RequestParam Integer uid) {
        Result<GetUserInfo> result = new Result<>();
        User user = getUser(uid);
        if(user == null) {
            result.setData(null);
        }else {
            result.setData(AccountAssembler.toUserInfo(user));
        }
        return result;
    }

    @Override
    public Result<List<GetUserInfo>> batchGetUserInfo(@RequestBody BatchGetUserReq batchGetUserReq) {
        Result<List<GetUserInfo>> result = new Result<>();

        List<Integer> uids = batchGetUserReq.getUids();
        logger.debug("batchGetUserInfo uids size {}", uids.size());
        List<User> users = getUsers(uids);
        logger.debug("batchGetUserInfo userinfo size {}", users.size());
        List<GetUserInfo> collect = users.stream().map(AccountAssembler::toUserInfo).collect(Collectors.toList());
        collect.forEach(user -> logger.debug("batchGetUserInfo userinfo {}", user.toString()));
        result.setData(collect);
        return result;
    }

    @Override
    public ImGetUserInfo validToken(@RequestParam String token, @RequestParam Long uid) {
        logger.info("validToken {} {}", token, uid);
        boolean valid = accountService.validToken(token, uid);
        logger.info("validToken result {}", valid);
        if (valid) {
            return AccountAssembler.toImUserInfo(getUser(Math.toIntExact(uid)));
        }
        return null;
    }

    @Override
    public Result<GetUserInfo> getMyInfo(@RequestHeader("uid") Integer userId) {
        Result<GetUserInfo> result = new Result<>();
        User user = getUser(userId);
        if(user == null) {
            result.setData(null);
        }else {
            result.setData(AccountAssembler.toUserInfo(user));
        }
        return result;

    }

    @Override
    public Result<GetUserInfoAndBind> getUserInfoAndBind(@RequestHeader("uid") Integer uid) {
        Result<GetUserInfoAndBind> userInfoAndBindResult = new Result<>();
        User user = getUser(uid);
        if(user == null) {
            userInfoAndBindResult.setData(null);
        }else {
//            BindInfo bindInfo = accountService.loadBindInfo(uid);
            userInfoAndBindResult.setData(AccountAssembler.toUserInfoAndBind(user, null));
        }
        return userInfoAndBindResult;
    }

    @Override
    public Result<Boolean> reportLocation(@RequestParam String location, @RequestHeader("uid") Integer userId) {
        Result<Boolean> result = new Result<>();
        try {
            boolean success = userService.updateLocation(location, userId);
            result.setData(success);
        } catch (Exception e) {
            if (e instanceof QuHuiRuntimeException) {
                result = ((QuHuiRuntimeException) e).createResult();
            } else {
                result = SystemExceptionEnum.UN_KNOW_ERROR.createResult();
            }
        }
        return result;
    }

    private User getUser(Integer id) {
        User userById = userService.getUserById(id);
        return userById;
    }

    private List<User> getUsers(List<Integer> ids) {
        return userService.getUsersByIds(ids);
    }

}
